package com.youths.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.youths.dao.*;
import com.youths.domain.*;
import com.youths.service.*;
import com.youths.util.HttpAPIUtil;
import com.youths.util.ImgReadToBase64;
import com.youths.util.ResultEnum;
import com.youths.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/7/8
 */
@Service
@Slf4j
public class RecognizationServiceImp implements RecognizationService {
    @Autowired(required = false)
    RecognizationMapper recognizationMapper;

    @Autowired(required = false)
    YouthInfoMapper youthInfoMapper;

    @Autowired(required = false)
    SliceMapper sliceMapper;

    @Autowired(required = false)
    ScoreMapper scoreMapper;

    @Autowired(required = false)
    HeightInfoMapper heightInfoMapper;

    @Autowired(required = false)
    SliceService sliceService;

    @Autowired
    YouthInfoService youthInfoService;

    @Autowired
    ScoreService scoreService;

    @Autowired
    HeightInfoService heightInfoService;

    @Autowired
    HttpAPIUtil httpAPIUtil;

    @Value("${url.slice}")
    String sliceUrl;

    @Value("${url.reco}")
    String recoUrl;

    @Value("${url.heightplot}")
    String heightPlotUrl;

//    @Override
//    public int addRecognization(Integer slicingID, Integer raoScore, Integer chiScore, Integer touScore, Integer gouScore,
//                                Integer zhang1Score, Integer zhang3Score, Integer zhang5Score,
//                                Integer jin1Score, Integer jin3Score, Integer jin5Score,
//                                Integer zhong3Score, Integer zhong5Score,
//                                Integer yuan1Score, Integer yuan3Score, Integer yuan5Score,
//                                Integer kind, Integer state) {
//        int result = recognizationMapper.add(slicingID, raoScore, chiScore, touScore, gouScore,
//                                             zhang1Score, zhang3Score, zhang5Score,
//                                             jin1Score, jin3Score, jin5Score,
//                                             zhong3Score, zhong5Score,
//                                             yuan1Score, yuan3Score, yuan5Score,
//                                             kind, state);
//        return result;
//    }


    @Override
    public int add(Recognization recognization) {
        int result = recognizationMapper.add(recognization);
        if (result > 0) {
            return recognization.getRecoId();
        }else {
            return result;
        }
    }

    @Override
    public List<Recognization> getRecogList(Integer slicingId) {
        List<Recognization> list = recognizationMapper.list(slicingId);
        return list;
    }

    @Override
    public Recognization query(Integer recoId) {
        return recognizationMapper.query(recoId);
    }

    @Override
    public int addChn(Recognization recognization) {
        int result = recognizationMapper.addChn(recognization);
        if (result > 0) {
            return recognization.getRecoId();
        }else {
            return 0;
        }
    }

    //error-0 slice update error = -1 true > 0
    @Override
    @Transactional
    public ResultEnum analysisProcess(Integer sliceId, Float height, Float weight, Integer youthId) {
        try {
            log.info("recogSId:" + sliceId);
            //切割
            ResultEnum result = getSlicePathAndSql(sliceId, height, weight, youthId);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultEnum.DEFAULT_ERROR;
    }


    //切割接口调用
    private ResultEnum getSlicePathAndSql(Integer sliceId, Float height, Float weight, Integer youthId) {
        try{
            //查询 获取接口参数信息
            Slice slice = sliceService.query(sliceId);
            if (slice == null) {
                return ResultEnum.NULL_ERROR;
            }else {
                Map<String, Object> param = new HashMap<>();
                String strPath = slice.getBoneImgPath();
                String [] array = strPath.split("/");
                String str = array[array.length-2];
                param.put("dir", str);
                param.put("path", str);
                //HttpResult result = httpAPIUtil.doGet(sliceUrl);
                HttpResult result = httpAPIUtil.doGet(sliceUrl + "/" + str + "/" + str);
                if (result.getCode() == 200) {
                    log.debug("切割接口请求成功");
                    CutEntity cutEntity = JSON.parseObject(result.getBody(), CutEntity.class);
                    if (cutEntity.getCode() == 0) {//todo
                        log.debug("切割接口返回正确");
                        String slicePath = cutEntity.getData();
                        int updateResult = sliceService.updateSliceInfo(height, weight, slicePath, youthId, sliceId,1);
                        log.debug("切割接口返回数据：" + cutEntity.getData());
//                        log.info("sliceJson:" + cutEntity.getData());
//                        log.info("update:" + updateResult);
                        if (updateResult > 0) {
                            //流程2 识别
                            log.debug("slice更新成功");
                            ResultEnum recoResult = getAnalysisResultAndSql(slicePath, youthId, sliceId);
                            return recoResult;
                        }else {
                            return ResultEnum.SLICE_UPDATE_ERROR;
                        }
                    }else {
                        return ResultEnum.SLICE_INTERFACE_ERROR;
                    }
                }else {
                    return ResultEnum.HTTP_ERROR;
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return ResultEnum.DEFAULT_ERROR;
    }

    //识别接口调用
    private ResultEnum getAnalysisResultAndSql(String slicePath, Integer youthId, Integer sliceId) {
        try {
            YouthInfo youth = youthInfoService.queryYouthInfo(youthId);
            Slice slice = sliceService.query(sliceId);
            if (youth == null) {
                return ResultEnum.NULL_ERROR;
            }else {
                log.debug("youth读取成功");
                Map<String, Object> param = new HashMap<>();
                param.put("image_path", slicePath);
                param.put("sex", youth.getYouthSex()); //0男  1女
                param.put("age", StringUtil.getAge(youth.getYouthBirth(), slice.getPhysicalTime()));

                HttpResult result = httpAPIUtil.doGet(recoUrl, param);
                //HttpResult result = httpAPIUtil.doPost(recoUrl, param);
                if (result.getCode() == 200) {
                    RecoEntity recoEntity = JSON.parseObject(result.getBody(), RecoEntity.class);
                    //ChnRecoEntity chnRecoEntity = JSON.parseObject(result.getBody(), ChnRecoEntity.class);
                    if (recoEntity.getCode().equals("success")) {
                        log.debug("识别接口请求正确");
                        log.debug("识别接口返回内容:" + recoEntity.getData());
                        Recognization recognization = new Recognization();
                        recognization.setRaoScore(recoEntity.getData().getRao());
                        recognization.setTouScore(recoEntity.getData().getTou());
                        recognization.setGouScore(recoEntity.getData().getGou());
                        recognization.setChiScore(recoEntity.getData().getChi());
                        recognization.setZhang1Score(recoEntity.getData().getZhang1());
                        recognization.setZhang3Score(recoEntity.getData().getZhang3());
                        recognization.setZhang5Score(recoEntity.getData().getZhang5());
                        recognization.setJin1Score(recoEntity.getData().getJin1());
                        recognization.setJin3Score(recoEntity.getData().getJin3());
                        recognization.setJin5Score(recoEntity.getData().getJin5());
                        recognization.setZhong3Score(recoEntity.getData().getZhong3());
                        recognization.setZhong5Score(recoEntity.getData().getZhong5());
                        recognization.setYuan1Score(recoEntity.getData().getYuan1());
                        recognization.setYuan3Score(recoEntity.getData().getYuan3());
                        recognization.setYuan5Score(recoEntity.getData().getYuan5());
                        recognization.setSlicingId(sliceId);
                        recognization.setKind(1); //ai
                        recognization.setState(0);
                        int recoId = add(recognization);

//                        Recognization chnRecognization = new Recognization();
//                        Recognization tw3Recognization = new Recognization();
//                        Recognization twcRecognization = new Recognization();
//                        setReco(chnRecognization, recoEntity, sliceId, 1);
//                        setReco(tw3Recognization, recoEntity, sliceId, 2);
//                        setReco(twcRecognization, recoEntity, sliceId, 3);
//                        //入库
//                        int chnId = add(chnRecognization);
//                        int tw3Id = add(tw3Recognization);
//                        int twcId = add(twcRecognization);
                        if (recoId > 0){
                            log.debug("reco入库成功");
                            //分值入库
                            Score score = new Score();
                            score.setRecoId(recoId);
                            score.setChnBoneage(recoEntity.getData().getChn_boneage());
                            score.setTw3Boneage(recoEntity.getData().getTw3_boneage());
                            score.setTwcBoneage(recoEntity.getData().getTwc_boneage());
                            score.setSituation(recoEntity.getData().getSituation());
                            score.setState(0);

//                            Score chnScore = new Score();
//                            chnScore.setRecoId(chnId);
//                            chnScore.setBoneAge(recoEntity.getData().getChn_boneage());
//                            chnScore.setSituation(recoEntity.getData().getSituation());
//                            chnScore.setState(0);
//
//                            Score tw3Score = new Score();
//                            tw3Score.setRecoId(tw3Id);
//                            tw3Score.setBoneAge(recoEntity.getData().getTw3_boneage());
//                            tw3Score.setState(0);
//
//                            Score twcScore = new Score();
//                            twcScore.setRecoId(twcId);
//                            twcScore.setBoneAge(recoEntity.getData().getTwc_boneage());
//                            twcScore.setState(0);
//
//                            int scoreChnId = scoreService.addScore(chnScore);
//                            int scoreTw3Id = scoreService.addScore(tw3Score);
//                            int scoreTwcId = scoreService.addScore(twcScore);
                            int scoreId = scoreService.addScore(score);
                            if (scoreId > 0) {
                                log.debug("score入库成功");
                                //分数 骨龄入库
                                //调用身高接口 todo
                                ResultEnum heightResultEnum = getHeightPlotAndSql(youth, sliceId, recoId, recoEntity.getData().getChn_boneage());
                                return heightResultEnum;
                            }else {
                                return ResultEnum.SCORE_ADD_ERROR;
                            }
                        }else {
                            return ResultEnum.RECO_ADD_ERROR;
                        }
                    }
                }else {
                    return ResultEnum.HTTP_ERROR;
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultEnum.DEFAULT_ERROR;
    }


    //身高接口调用  骨龄直接传
    private ResultEnum getHeightPlotAndSql(YouthInfo youth, Integer sliceId, Integer recoId, Float boneAge) {
        try {
            Slice slice = sliceService.query(sliceId);
            //Recognization recognization = query(recoId);
            if (slice == null) {
                return ResultEnum.NULL_ERROR;
            }else {
                log.debug("slice获取成功");
                Map<String, Object> param = new HashMap<>();
                //计算年龄替换数据todo
                param.put("age", StringUtil.getAge(youth.getYouthBirth(),slice.getPhysicalTime()));
                param.put("boneage", boneAge);
                String sexArray[] = {"男", "女"};
                param.put("sex", sexArray[youth.getYouthSex()]);
                param.put("height",slice.getHeight());
                param.put("yichuanx", youth.getYouthMotherHeight());
                param.put("yichuany", youth.getYouthFatherHeight());

                //HttpResult result = httpAPIUtil.doPost(heightPlotUrl, param);
                //HttpResult result = httpAPIUtil.doPost(heightPlotUrl, param);
                HttpResult result = httpAPIUtil.doGet(heightPlotUrl, param);
                //HttpResult result = httpAPIUtil.doGet("http://localhost:8090/heightplot2");
                if (result.getCode() == 200) {
                    log.debug("身高接口调用成功:" + result.getBody());
                    //返回数据 无成功失败判定 todo
                    //String body = httpAPIUtil.doGet("http://localhost:8090/heightplot2");
                    //System.out.println(body);
                    HeightEntity heightEntity = JSON.parseObject(result.getBody(), HeightEntity.class);
                    //HeightEntity heightEntity = JSON.parseObject(body, HeightEntity.class);

                    HeightInfo heightInfo = new HeightInfo();
                    heightInfo.setRecoId(recoId);
                    heightInfo.setBpForecastHeight(heightEntity.getBp());
                    heightInfo.setImproveBpForecastHeight(heightEntity.getBp2());
                    heightInfo.setGeneticHeight(heightEntity.getTarget());
                    heightInfo.setGrowthTrend(StringUtil.jsonArrayToString(heightEntity.getForecast()));
                    heightInfo.setEvaluate(heightEntity.getMessage());
                    heightInfo.setState(0);
                    int heightId = heightInfoService.addHeightInfo(heightInfo);
                    if (heightId > 0) {
                        log.debug("height入库成功");
                        sliceService.updateState(sliceId, 2);
                        return ResultEnum.CODE_OK;
                    }else {
                        return ResultEnum.HEIGHT_ADD_ERROR;
                    }
                }else {
                    return ResultEnum.HTTP_ERROR;
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return ResultEnum.DEFAULT_ERROR;
    }

    @Override
    public int updateRank(Recognization recognization) {
        return recognizationMapper.updateRank(recognization);
    }

    //    private void setReco(Recognization recognization, RecoEntity recoEntity, Integer sliceId, Integer kind) {
//        recognization.setRaoScore(recoEntity.getData().getRao());
//        recognization.setTouScore(recoEntity.getData().getTou());
//        recognization.setGouScore(recoEntity.getData().getGou());
//        recognization.setChiScore(recoEntity.getData().getChi());
//
//        recognization.setZhang1Score(recoEntity.getData().getZhang1());
//        recognization.setZhang3Score(recoEntity.getData().getZhang3());
//        recognization.setZhang5Score(recoEntity.getData().getZhang5());
//
//        recognization.setJin1Score(recoEntity.getData().getJin1());
//        recognization.setJin3Score(recoEntity.getData().getJin3());
//        recognization.setJin5Score(recoEntity.getData().getJin5());
//
//        recognization.setZhong3Score(recoEntity.getData().getZhong3());
//        recognization.setZhong5Score(recoEntity.getData().getZhong5());
//
//        recognization.setYuan1Score(recoEntity.getData().getYuan1());
//        recognization.setYuan3Score(recoEntity.getData().getYuan3());
//        recognization.setYuan5Score(recoEntity.getData().getYuan5());
//
//        recognization.setSlicingId(sliceId);
//        recognization.setKind(kind); //1-chn
//        recognization.setState(0);
//    }











    @Override
    public PageInfo getRecoList(Integer pageNum, Integer type, String date1, String date2, Integer recoId, Integer slicingId, String card) {
        PageHelper.startPage(pageNum,10);
        List<YouthInfo> youthInfos = null;
        List<Slice> slices = null;
        if(card != null && !card.equals("")){
            youthInfos = youthInfoMapper.getList(null,null,card,null);
            if(youthInfos.size()==0){
                return new PageInfo();
            } else {
                slices = sliceMapper.getList(null,null,null,youthInfos);
            }
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try{
            if(date2 != null && !date2.equals("")){
                if(date1 != null && !date1.equals("") && simpleDateFormat.parse(date1).after(simpleDateFormat.parse(date2))){
                    String temp = date1;
                    date1 = date2;
                    date2 = temp;
                }
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(simpleDateFormat.parse(date2));
                calendar.add(calendar.DATE,1);
                date2 = simpleDateFormat.format(calendar.getTime());
                System.out.println(date2);
            }
        }catch (Exception e){ }
        List<Recognization> recognizations = recognizationMapper.getList(type,date1,date2,recoId,slicingId,slices);
        PageInfo<Recognization> recognizationPageInfo = new PageInfo<>(recognizations);
        return recognizationPageInfo;
    }

    @Override
    public JSONObject getRecoDetail(Integer recoId, Integer slicingId) {
        JSONObject jsonObject = new JSONObject();
        List<Score> scores = new ArrayList<>();
        List<HeightInfo> heightInfos = new ArrayList<>();
        List<YouthInfo> youthInfos = new ArrayList<>();
        List<Slice> slices = new ArrayList<>();
        if(recoId != null && recoId != 0) {
            scores = scoreMapper.getList(recoId);
            heightInfos = heightInfoMapper.getList(recoId);
        }
        if(slicingId != null && slicingId != 0){
            slices = sliceMapper.getList(slicingId,null,null,null);
            if(slices.size()>0 && slices.get(0).getYouthId()!=null && slices.get(0).getYouthId()!=0){

                youthInfos = youthInfoMapper.getList(slices.get(0).getYouthId(),null,null,null);
            }
        }
        String dir = slices.get(0).getSlicingPath();
        String []dirs = dir.split("/");
        jsonObject.put("img",ImgReadToBase64.readImage(dir+"/"+dirs[dirs.length-1]+"_det.jpg"));
        jsonObject.put("youth",youthInfos.size()>0?youthInfos.get(0):null);
        jsonObject.put("slicing",slices.size()>0?slices.get(0):null);
        jsonObject.put("boneScore",scores.size()>0?scores.get(0):null);
        jsonObject.put("heightInfo",heightInfos.size()>0?heightInfos.get(0):null);
        return jsonObject;
    }
}
